import Snake, { snakes } from './Snake.js';
import Bug, { bugs } from './Bug.js';
import config from './config.js';

export default class Play {
    rate = config.rate;
    direction;
    intervalId;
    constructor(app) {
        this.app = app;
        this.bindDocumentEvent();
    }

    reset() {
        clearInterval(this.intervalId);
        this.play(this.rate);
    }

    restart() {
        this.app.renderTotal('重新开始！');
        Snake.remove();
        Bug.remove();
        this.app.snake({ bgColor: 'green', ...this.app.randomPosition() });
        this.app.bug();
        this.direction = '';
        this.rate = config.rate;
        this.play(config.rate);
    }

    play(rate) {
        this.intervalId = setInterval(this.run.bind(this), rate);
    }

    run() {
        snakes.reduce((position, snake) => {
            snake.left = position.left;
            snake.top = position.top;
            return snake.oldPosition;
        }, this.position());

        //检测与小虫的碰撞
        this.bugCrash();
        //检测与画布的碰撞
        this.canvasCrash();
    }

    bugCrash() {
        if (Snake.first.left == Bug.left && Snake.first.top == Bug.top) {
            Bug.remove();
            this.app.snake({
                left: Snake.last.oldPosition.left,
                top: Snake.last.oldPosition.top,
            });
            this.app.renderTotal();
            this.app.bug();
            this.rate = Math.max(50, this.rate - 10);
            this.reset();
        }
    }

    canvasCrash() {
        let head = Snake.first;
        if (
            head.left < 0 ||
            head.left > this.app.options.width - 50 ||
            head.top < 0 ||
            head.top > this.app.options.height - 50
        ) {
            this.gameover();
        }
    }

    gameover() {
        clearInterval(this.intervalId);
        this.app.renderTotal('游戏结束！');
    }

    bindDocumentEvent() {
        document.addEventListener('keydown', (event) => {
            this.direction = event.key.substr(5).toLowerCase();
            if (!this.intervalId) this.play(this.rate);
        });
    }

    position() {
        const position = { left: Snake.first.left, top: Snake.first.top };
        switch (this.direction) {
            case 'left':
                position.left -= 50;
                break;
            case 'up':
                position.top -= 50;
                break;
            case 'down':
                position.top += 50;
                break;
            case 'right':
                position.left += 50;
                break;
        }
        return position;
    }
}
